/**
 * @depends nothing
 * @name core.date
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 */

/**
 * Apply the Datetime string to the current Date object
 * Datetime string in the format of "year month day hour min sec". "hour min sec" all optional.
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.setDatetimestr = Date.prototype.setDatetimestr || function(timestamp){
	// Set the datetime from a string
	var pieces = timestamp.split(/[\-\s\:]/g);
	var year = pieces[0];
	var month = pieces[1];
	var day = pieces[2];
	var hour = pieces[3]||0;
	var min = pieces[4]||0;
	var sec = pieces[5]||0;
	this.setUTCFullYear(year,month-1,day);
	this.setUTCHours(hour);
	this.setUTCMinutes(min);
	this.setUTCSeconds(sec);
	return this;
};

/**
 * Apply the Date string to the current Date object
 * Date string in the format of "year month day". "year month day" all optional.
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.setDatestr = Date.prototype.setDatestr || function(timestamp){
	// Set the date from a string
	var pieces = timestamp.split(/[\-\s\:]/g);
	var year = pieces[0]||1978;
	var month = pieces[1]||0;
	var day = pieces[2]||1;
	this.setUTCFullYear(year,month-1,day);
	return this;
};

/**
 * Apply the Time string to the current Date object
 * Time string in the format of "hour min sec". "hour min sec" all optional.
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.setTimestr = Date.prototype.setTimestr || function(timestamp){
	// Set the time from a string
	var pieces = timestamp.split(/[\-\s\:]/g);
	var hour = pieces[0]||0;
	var min = pieces[1]||0;
	var sec = pieces[2]||0;
	this.setUTCHours(hour);
	this.setUTCMinutes(min);
	this.setUTCSeconds(sec);
	return this;
};

/**
 * Return the Date as a Datetime string
 * Datetime string in the format of "year-month-date hours:minutes:seconds".
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.getDatetimestr = Date.prototype.getDatetimestr || function() {
	// Get the datetime as a string
	var date = this;
	return date.getDatestr()+' '+date.getTimestr();
};

/**
 * Return the Date as a Datetime string
 * Datetime string in the format of "year-month-date".
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.getDatestr = Date.prototype.getDatestr || function() {
	// Get the date as a string
	var date = this;
	var year = date.getUTCFullYear();
	var month = (this.getUTCMonth() + 1).padLeft(0,2);
	var date = this.getUTCDate().padLeft(0,2);
	return year+'-'+month+'-'+date;
};

/**
 * Return the Date as a Datetime string
 * Datetime string in the format of "hours:minutes:seconds".
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.getTimestr = Date.prototype.getTimestr || function(){
	// Get the time as a string
	var date = this;
	var hours = date.getUTCHours().padLeft(0,2);
	var minutes = date.getUTCMinutes().padLeft(0,2);
	var seconds = date.getUTCSeconds().padLeft(0,2);
	return hours+':'+minutes+':'+seconds;
};

/**
 * Return the Date as a ISO 8601 date string
 * @version 1.0.0
 * @date June 30, 2010
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
 */
Date.prototype.getDatetime = String.prototype.getDatetime || function(){
	// Get a ISO 8601 date
	var now = this;
	var datetime = now.getUTCFullYear() + '-' +
		(now.getUTCMonth()+1).zeroise(2) + '-' +
		now.getUTCDate().zeroise(2) + 'T' +
		now.getUTCHours().zeroise(2) + ':' +
		now.getUTCMinutes().zeroise(2) + ':' +
		now.getUTCSeconds().zeroise(2) + '+00:00';
	return datetime;
};

/**
 * @depends jquery, core.console
 * @name jquery.balclass
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 */

/**
 * jQuery Aliaser
 */
(function($){
	
	/**
	 * BalClass
	 * @version 1.5.0
	 * @date August 28, 2010
	 * @since 1.0.0, June 30, 2010
     * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
	 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
	 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
	 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
	 */
	if ( !($.BalClass||false) ) {
		// Constructor
		$.BalClass = function(extend){
			this.construct(extend);
		};
		// Prototype
		$.extend($.BalClass.prototype, {
			config: {
			},
			construct: function(){
				var Me = this,
					extend = {};
				// Handle
				if ( typeof arguments[0] === 'object' && typeof arguments[1] === 'object'  ) {
					// config, extend
					extend = arguments[1];
					extend.config = arguments[0]||{};
				}
				else if ( typeof arguments[0] === 'object' ) {
					// extend
					extend = arguments[0];
					extend.config = extend.config||{};
				}
				else if ( typeof arguments[0] === 'undefined' ) {
					// No arguments were passed
					extend = false;
				}
				else {
					window.console.error('BalClass.construct: Invalid Input');
				}
				
				// Check
				if ( extend !== false ) {
					// Configure
					Me.configure(extend.config);
					delete extend.config;
				
					// Extend
					$.extend(Me,extend);
				}
				
				// Build
				if ( typeof Me.built === 'function' ) {
					return Me.built();
				}
				
				// Return true
				return true;
			},
			configure: function(config){
				var Me = this;
				Me.config = Me.config||{};
				Me.config = $.extend({},Me.config,config||{}); // we want to clone
				return Me;
			},
			clone: function(extend){
				// Clone a BalClass (Creates a new BalClass type)
				var Me = this;
				var clone = function(extend){
					this.construct(extend);
				};
				$.extend(clone.prototype, Me.prototype, extend||{});
				clone.clone = clone.prototype.clone;
				clone.create = clone.prototype.create;
				return clone;
			},
			create: function(Extension){
				// Create a BalClass (Creates a new instance of a BalClass)
				var Me = this;
				var Obj = new Me(Extension);
				return Obj;
			},
			addConfig: function(name, config){
				var Me = this;
				if ( typeof config === 'undefined' ) {
					if ( typeof name === 'object' ) {
						// Series
						$.each(name,function(key,value){
							Me.applyConfig(key, value);
						});
					}
					return false;
				} else if ( typeof config === 'object' ) {
					// Single
					Me.applyConfig(name, config);
				}
				return Me;
			},
			applyConfig: function(name,config){
				var Me = this;
				Me.config[name] = Me.config[name]||{};
				$.extend(true,Me.config[name],config||{});
				return Me;
			},
			setConfig: function(name,config){
				var Me = this;
				Me.config[name] = config||{};
				return Me;
			},
			hasConfig: function(name){
				var Me = this;
				return typeof Me.config[name] !== 'undefined';
			},
			getConfig: function(name){
				var Me = this;
				if ( typeof name !== 'string' ) {
					return this.config;
				}
				return this.getConfigWith(name);
			},
			getConfigWith: function(name,config){
				var Me = this;
				if ( typeof name !== 'string' ) {
					if ( typeof config === 'undefined' ) {
						config = name;
					}
					name = 'default';
				}
				if ( typeof config !== 'object' ) {
					config = {};
				}
				var result = {};
				$.extend(true, result, Me.config[name]||{}, config||{});
				return result;
			},
			getConfigWithDefault: function(name,config){
				var Me = this;
				return Me.getConfigWith('default',Me.getConfigWith(name,config));
			},
			setDefaults: function(config){
				var Me = this;
				return Me.applyConfig('default',config);
			}
		});
		// Instance
		$.BalClass.clone = $.BalClass.prototype.clone;
		$.BalClass.create = $.BalClass.prototype.create;
		// ^ we alias these as they should be both in prototype and instance
		//   however we do not want to create a full instance yet...
	}
	else {
		window.console.warn("$.BalClass has already been defined...");
	}


})(jQuery);
/**
 * @depends jquery, core.console, jquery.balclass
 * @name jquery.balclass.eventcalendar
 * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
 */

/**
 * jQuery Aliaser
 */
(function($){
	
	/**
	 * Event Calendar
	 * @version 1.2.1
	 * @date August 20, 2010
	 * @since 1.0.0, June 30, 2010
     * @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
	 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
	 * @copyright (c) 2009-2010 Benjamin Arthur Lupton {@link http://www.balupton.com}
	 * @license GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
	 */
	if ( !($.EventCalendar||false) ) {
		$.EventCalendar = $.BalClass.create({
			// Configuration
			config: {
				// Default Mode
				"default": {
					// Ajax Variables
					/** The JSON variable that will be return on the AJAX request which will contain our entries */
					ajaxEntriesVariable: 'entries',
					/** The AJAX url to request for our entries */
					ajaxEntriesUrl: '',
					/** The JSON Object to send via POST to our AJAX request */
					ajaxPostData: {},
					/** Whether or not to Cache the AJAX data */
					ajaxCache: true,
				
					// Data Variables
					/* If you are not using AJAX, you can define your entries here */
					calendarEntries: [],
				
					// Customisation Variables
					/** The CSS class which will be assigned to the Event Calendar */
					calendarClass: 'hasEventCalendar',
					/** The CSS class which will be assigned to day when the day contains a entry */
					dayEventClass: 'ui-state-active hasEvent',
					/** The standard options to send to the datepicker */
					datepickerOptions: {},
					/** Whether or not to disable the datepicker date selection click */
					disableClick: true,
					/**
					 * Whatever events you would like to assign to a $day
					 * You will recieve the arguments: domEvent, day, dayEntries, entries
					 */
					domEvents: {}
				}
			},
			// Functions
			/**
			 * jQuery Object Function
			 */
			fn: function(mode,options){
				var EventCalendar = $.EventCalendar;
				
				// Group?
				var $calendar = $(this);
				if ( $calendar.length > 1 ) {
					$calendar.each(function(){
						$(this).EventCalendar(mode,options);
					});
					return this;
				}
				
				// Prepare
				var Me = $.EventCalendar;
				var config = Me.getConfigWithDefault(mode,options);
				
				// Initialise
				var Entries = {
					/**
					 * Calendar Entries Stored by {entryId:entry}
					 */
					entriesById: {},
					
					/**
					 * Calendar Entries Stored by {"year-month":[entry,entry]}
					 */
					entriesByYearMonth: {},
					
					/**
					 * Whether or not the "year-month" is cacheable
					 */
					cacheableByYearMonth: {},
					
					/**
					 * Get whether or not a "year-month" is cacheable
					 */
					isCacheable: function(year,month,value){
						return (this.cacheableByYearMonth[year+'-'+month]||false) ? true : false;
					},
					
					/**
					 * Set whether or not a "year-month" is cacheable
					 */
					setCacheable: function(year,month,value){
						if ( typeof value === 'undefined' ) value = 
						this.cacheableByYearMonth[year+'-'+month] = value;
						return this;
					},
					
					/**
					 * Calendar Entries Undefined
					 */
					isYearMonthSet: function(year,month) {
						return typeof this.entriesByYearMonth[year+'-'+month] !== 'undefined';
					},
					
					/**
					 * Calendar Entries Empty
					 */
					isYearMonthEmpty: function(year,month) {
						var notempty =
							(typeof this.entriesByYearMonth[year+'-'+month] === 'array' && this.entriesByYearMonth[year+'-'+month].length !== 0) ||
							(typeof this.entriesByYearMonth[year+'-'+month] === 'object' && !$.isEmptyObject(this.entriesByYearMonth[year+'-'+month]))
						;
						return !notempty;
					},
					
					/**
					 * Calendar Entries Getter
					 */
					getEntriesByYearMonth: function(year,month) {
						return this.entriesByYearMonth[year+'-'+month]||[];
					},
					
					/**
					 * Calendar Entries Getter
					 */
					getEntryById: function(id) {
						return this.entriesById[id]||undefined;
					},
					
					/**
					 * Get Days in a Month by passing a date
					 */
					getDaysInMonth: function(date){
						// http://snippets.dzone.com/posts/show/2099
						return 32 - new Date(date.getFullYear(), date.getMonth(), 32).getDate();
					},
					
					/**
					 * Get Date
					 */
					getDate: function(timestamp){
						// Convert
						var date;
						if ( typeof timestamp === 'string' ) {
							date = new Date(timestamp);
						}
						else if ( typeof timestamp === 'number' ) {
							date = new Date();
							date.setTime(timestamp);
						}
						else if ( typeof timestamp === 'object' ) {
							date = new Date();
							date.setTime(timestamp.getTime());
						}
						else {
							throw Error("Unknown date format.");
						}
						
						// Fix for Firefox
						if ( isNaN(date) || date.toString() === "Invalid Date" ) {
							date = new Date();
							date.setDatetimestr(timestamp);
						}
						
						// Return date
						return date;
					},

					/**
					 * Calendar Entries Setter
					 */
					addEntries: function(entries) {
						// Prepare
						var Me = this;
						
						// Add
						$.each(entries,function(index,entry){
							// Prepare
							entry.id = entry.id||index;
							
							// Add Entry
							Me.addEntry(entry);
						});
						
						// Chain
						return true;
					},
					
					/**
					 * Calendar Entries Setter
					 */
					addEntry: function(entry) {
						// Prepare entry
						entry.start = this.getDate(entry.start);
						entry.finish = this.getDate(entry.finish);
						
						// Cycle through years and months
						var currentDate = this.getDate(entry.start);
						currentDate.setDate(1); currentDate.setHours(0); currentDate.setMinutes(0); currentDate.setSeconds(0); currentDate.setMilliseconds(0);
						var finishDate = this.getDate(entry.finish);
						finishDate.setDate(2); finishDate.setHours(0); finishDate.setMinutes(0); finishDate.setSeconds(0); finishDate.setMilliseconds(0);
						while ( currentDate < finishDate ) {
							// Fetch
							var year = currentDate.getFullYear(),
								month = currentDate.getMonth()+1;
							
							/*
							// Add
							entry.span = entry.span||{};
							entry.span[year] = entry.span[year]||{};
							entry.span[year][month] = entry.span[year][month]||{};
							
							// Cycle through days
							// Determine span
							var firstMonth = (year === entry.start.getFullYear() && month === entry.start.getMonth()+1),
								lastMonth = (year === entry.finish.getFullYear() && month === entry.finish.getMonth()+1),
								daysInMonth = this.getDaysInMonth(currentDate);
							// Ifs
							if ( firstMonth && lastMonth ) {
								// First + Last
								// Get days between (inclusive)
								var startDay = entry.start.getDate(),
									finishDay = entry.finish.getDate();
							else if (  ) {
								// First
								// Get days from (inclusive)
								var startDay = entry.start.getDate(),
									finishDay = daysInMonth;
							}
							else if (  ) {
								// Last
								// Get days to (inclusive)
								var startDay = 1,
									finishDay = entry.finish.getDate();
							}
							else {
								// Intermediate
								// Get all days
								var startDay = 1,
									finishDay = daysInMonth;
							}
							// Apply
							for ( var day = startDay; day<=finishDay; ++day ) {
								entry.span[year][month][day] = true;
							}
							*/
							
							// Add to Year-Month Indexed
							if ( typeof this.entriesByYearMonth[year+'-'+month] === 'undefined' ) {
								this.entriesByYearMonth[year+'-'+month] = {};
							}
							this.entriesByYearMonth[year+'-'+month][entry.id] = entry;
							
							// Increment date by one month
							if ( month === 11 ) {
								currentDate.setMonth(0);
								currentDate.setYear(year+1);
							}
							else {
								currentDate.setMonth(month+1);
							}
						}
						
						// Add to ID Indexed
						this.entriesById[entry.id] = entry;
						
						// Return entry
						return entry;
					}
				};
				
				// Add the passed entries (if any)
				Entries.addEntries(config.calendarEntries);
				
				// Our Extender Event
				var calendarEntriesRender = function(datepicker, year, month) {
					// Fetch the Entries
					var monthEntries = Entries.getEntriesByYearMonth(year,month),
						$datepicker = $(datepicker);
					
					// Reset the Render
					var $days_tds = $datepicker.find('tbody td'),
						$days = $days_tds.find('a');
	
					// Aivan
                    // Disable Click
					if ( config.disableClick ) {
						$days_tds.unbind('click').removeAttr('onclick');
						$days.removeAttr('href').css('cursor','default');
					}

                    
                    //$.each($days, function(entryIndex,entry){
                    //    var month = (parseInt($(".ui-datepicker-month").val())+1) + '';
                    //    var year = $(".ui-datepicker-year").val()+ '';
                    //    var day = (entryIndex+1);
                    //    var date =  pad2(month) + "%2f" + pad2(day) + "%2f" + year;
                    //    var string = sprintf("/events/search?datestart=%s",date);
                    //    $(entry).attr("href",string);
                    //});
                    //$days.css('cursor','pointer');
	
    
					// Cycle Through Entries
					$.each(monthEntries, function(entryIndex,entry){
						// Fetch stat and finish days
						var startMonth = entry.start.getMonth()+1,
						 	finishMonth = entry.finish.getMonth()+1,
							startDay = entry.start.getDate(),
							finishDay = entry.finish.getDate();
						
						// Determine start and finish days in the rendered calendar
						var $startDay = startMonth == month ? $days.filter(':contains('+startDay+'):first') : $days.filter(':first'),
							$finishDay = finishMonth == month ? $days.filter(':contains('+finishDay+'):first') : $days.filter(':last');
						
						// Determine the indexes
						var start = startMonth == month ? $days.index($startDay) : 0,
							finish = finishMonth == month ? $days.index($finishDay) : $days.length-1,
							duration = finish-start+1; // +1 to be inclusive
						
						// Betweens
						var $entryDays = [];
						if ( start == finish ) {
							$entryDays = $startDay;
						} else if ( start == finish-1 ) {
							$entryDays = $startDay.add($finishDay);
						} else {
							$entryDays = $startDay.add($days.filter(':lt('+(finish)+')').filter(':gt('+(start)+')')).add($finishDay);
						}
						

                        // Add the Entry to These Days
                        //config.dayEventClass
						$entryDays.addClass(config.dayEventClass).each(function(dayIndex,dayElement){
							// Fetch
							var $day = $(dayElement),
								day = $day.text().trim(),
								dayEntriesIds = $day.data('dayEntriesIds');
			
							// Handle
							if ( typeof dayEntriesIds === 'undefined' ) {
								dayEntriesIds = entry.id;
							} else {
								dayEntriesIds = String(dayEntriesIds).split(/,/g);
								dayEntriesIds.push(entry.id);
								dayEntriesIds = dayEntriesIds.join(',');
							}
			
			                // Aivan
                           //var month = (parseInt($(".ui-datepicker-month").val())+1) + '';
                           //var year = $(".ui-datepicker-year").val()+ '';

            				// Apply
							$day.data('dayEntriesIds',dayEntriesIds);
			
							// Bind Entries
							$.each(config.domEvents,function(domEventName,domEventHandler){
								$day.unbind(domEventName).bind(domEventName,function(domEvent){
									// Prepare
									var $day = $(this),
										day = $day.text().trim(),
										dayEntriesIds = String($day.data('dayEntriesIds')).split(/,/g),
										date = new Date(); date.setDatestr(year+'-'+month+'-'+day);

									// Aivan
                                    var dateStr =  pad2(month) + "%2f" + pad2(day) + "%2f" + year;
                                    var string = sprintf("/events/search?datestart=%s",dateStr);
                                    $day.attr("href",string);
                                    $day.removeAttr("style");

									// Entries
									var dayEntries = []
									$.each(dayEntriesIds,function(i,entryId){
										var dayEntry = Entries.getEntryById(entryId);
										dayEntries.push(dayEntry);
									});
									
									// Fire
									domEventHandler.apply(this, [domEvent, {
										"year":year,
										"month":month,
										"day":day,
										"date":date,
										"dayEntries":dayEntries,
										"monthEntries":monthEntries,
										"datepicker":datepicker
									}]);
									
									// Done
									return true;
								});
							});
			
							// Done
						});
					});
	
					// Done
					return true;
				};
				
				// Change Month Year
				var calendarChangeMonthYear = function(year, month, inst) {
					// Prepare
					var datepicker = inst.dpDiv||inst;
					
					// Check
					if ( typeof config.ajaxEntriesUrl === 'string' && config.ajaxEntriesUrl.length ) {
						// Ajax Enabled
						if ( config.ajaxCache && Entries.isCacheable(year,month) && !Entries.isYearMonthEmpty(year,month) ) {
							// We can use the cache
							// And we have entries
							setTimeout(function(){
								calendarEntriesRender(datepicker, year, month)
							},50);
						}
						else {
							// Prepare
							var data = $.extend({},{
									year: year,
									month: month
								},
								config.ajaxPostData
							);
							// Fetch into the cache
							$.ajax({
								"url":  config.ajaxEntriesUrl,
								"method": 'post',
								"dataType": 'json',
								"data": data,
								success: function(data, status){
									// Cycle
									var entries = data[config.ajaxEntriesVariable]||[];
									
									// Enable caching for this year month
									Entries.setCacheable(year,month,true)
									
									// Check if we have entries
									if ( entries.length === 0 ) {
										return true;
									}
								
									// Store the Entries in the Calendar Data
									Entries.addEntries(entries);
								
									// Render the year and month, as we have new data
									setTimeout(function(){
										calendarEntriesRender(datepicker, year, month)
									},50);
									
									// Done
									return true;
								},
								error: function(XMLHttpRequest, textStatus, errorThrown, response_data){
									// Error
									window.console.warn('$.EventCalendar.calendarChangeMonthYear.ajax.error:', [this, arguments]);
								}
							});
						}
					}
					else if ( !Entries.isYearMonthEmpty(year,month) ) {
						// We are not using cache
						// And we have entries
						setTimeout(function(){
							calendarEntriesRender(datepicker, year, month)
						},50);
					}
					
					// Done
					return true;
				};
				
				// Prepare initial render
				var calendarInitialised = false;
				var calendarInit = function(year,month,inst){
					// Prepare
					if ( calendarInitialised ) return;
					calendarInitialised = true;
					// Apply
					$(inst).addClass(config.calendarClass);
					calendarChangeMonthYear(year, month, inst);
				};
				
				// Calendar Options
				var datepickerOptions = $.extend({}, config.datepickerOptions, {
					onChangeMonthYear: function(year, month, inst) {
						// Our Event
						calendarChangeMonthYear(year,month,inst);
						// Users' Event
						if ( typeof config.datepickerOptions.onChangeMonthYear === 'function' ) {
							calendarInit(year,month,inst);
						}
					},
					beforeShow: function(input, inst) {
						datepickerShowed = true;
						// Users' Event
						if ( typeof config.datepickerOptions.beforeShow === 'function' ) {
							config.datepickerOptions.beforeShow.apply(this,[input,inst]);
						}
						// Our Event
						setTimeout(function(){
							calendarInit(inst.drawYear, inst.drawMonth+1, inst);
						},1000);
					}
				});
				
				// Apply Options so we can hook into the events
				$calendar.datepicker(datepickerOptions);

				// Fallback in case beforeShow fails us
				setTimeout(function(){
					var date = $calendar.datepicker("getDate");
					calendarInit(date.getFullYear(), date.getMonth()+1, $calendar);
				},2000);
				
				// Chain
				return $calendar;
			},
			built: function(){
				// Prepare
				var Me = this;
				// Attach
				$.fn.EventCalendar = function(mode,options) {
					// Alias
					return Me.fn.apply(this,[mode,options]);
				};
				// Return true
				return true;
			}
		});
	}
	else {
		window.console.warn("$.EventCalendar has already been defined...");
	}


})(jQuery);

function pad2(number) {
   
     return (number < 10 ? '0' : '') + number
   
}


var sprintf=function(){function j(d){return Object.prototype.toString.call(d).slice(8,-1).toLowerCase()}var g=function(){g.cache.hasOwnProperty(arguments[0])||(g.cache[arguments[0]]=g.parse(arguments[0]));return g.format.call(null,g.cache[arguments[0]],arguments)};g.format=function(d,f){var i=1,k=d.length,a="",h=[],e,c,b,l;for(e=0;e<k;e++){a=j(d[e]);if(a==="string")h.push(d[e]);else if(a==="array"){b=d[e];if(b[2]){a=f[i];for(c=0;c<b[2].length;c++){if(!a.hasOwnProperty(b[2][c]))throw sprintf('[sprintf] property "%s" does not exist', b[2][c]);a=a[b[2][c]]}}else a=b[1]?f[b[1]]:f[i++];if(/[^s]/.test(b[8])&&j(a)!="number")throw sprintf("[sprintf] expecting number but found %s",j(a));switch(b[8]){case "b":a=a.toString(2);break;case "c":a=String.fromCharCode(a);break;case "d":a=parseInt(a,10);break;case "e":a=b[7]?a.toExponential(b[7]):a.toExponential();break;case "f":a=b[7]?parseFloat(a).toFixed(b[7]):parseFloat(a);break;case "o":a=a.toString(8);break;case "s":a=(a=String(a))&&b[7]?a.substring(0,b[7]):a;break;case "u":a=Math.abs(a); break;case "x":a=a.toString(16);break;case "X":a=a.toString(16).toUpperCase()}a=/[def]/.test(b[8])&&b[3]&&a>=0?"+"+a:a;c=b[4]?b[4]=="0"?"0":b[4].charAt(1):" ";l=b[6]-String(a).length;if(b[6]){c=c;l=l;for(var m=[];l>0;m[--l]=c);c=m.join("")}else c="";c=c;h.push(b[5]?a+c:c+a)}}return h.join("")};g.cache={};g.parse=function(d){d=d;for(var f=[],i=[],k=0;d;){if((f=/^[^\x25]+/.exec(d))!==null)i.push(f[0]);else if((f=/^\x25{2}/.exec(d))!==null)i.push("%");else if((f=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(d))!== null){if(f[2]){k|=1;var a=[],h=f[2],e=[];if((e=/^([a-z_][a-z_\d]*)/i.exec(h))!==null)for(a.push(e[1]);(h=h.substring(e[0].length))!=="";)if((e=/^\.([a-z_][a-z_\d]*)/i.exec(h))!==null)a.push(e[1]);else if((e=/^\[(\d+)\]/.exec(h))!==null)a.push(e[1]);else throw"[sprintf] huh?";else throw"[sprintf] huh?";f[2]=a}else k|=2;if(k===3)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";i.push(f)}else throw"[sprintf] huh?";d=d.substring(f[0].length)}return i};return g}(),vsprintf= function(j,g){g.unshift(j);return sprintf.apply(null,g)};